﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using WebServer;
using WebServer.Handlers;
using BusStopDataAccess;
using Common;
using System.IO;
using Common.Logging;

namespace BusStopWebApp.Services
{
    class BusStopLookup
    {
        private static readonly ILog log = LogManager.GetCurrentClassLogger();
        private const double DEFAULT_RANGE_KM = 1;
        private const int DEFAULT_MAX_RESULTS = 10;
        private static readonly TimeSpan DEFAULT_TIME_RANGE = TimeSpan.FromHours(1);

        private FileInfo _dbFile;
        public BusStopLookup(System.IO.FileInfo dbFile)
        { _dbFile = dbFile; }

        private IScheduleInfo DB()
        { 
            var temp =ScheduleInfoFactory.OpenDatabaseFile(_dbFile);
            temp.Log = new LogProxy(log, LogLevel.Trace) ;
            return temp;
        }

        [RestFunction]
        public IEnumerable<JSONBusStop> StopsNearMe(decimal lat, decimal lon, double rangeInKm = DEFAULT_RANGE_KM, int maxResults = DEFAULT_MAX_RESULTS)
        {
            using (IScheduleInfo db = DB())
            { return Serializer.Serialize(CommonQueries.StopsNearPoint(db, lat, lon, rangeInKm, maxResults)); }
        }

        [RestFunction(Cacheable = true, ExpiryInMinutes = 10)]
        public IEnumerable<JSONBusStop> StopByCode(String code)
        {
            using (IScheduleInfo db = DB())
            { return Serializer.Serialize(CommonQueries.StopByCode(db, code)); }
        }

        [RestFunction(Cacheable = true, ExpiryInMinutes = 10)]
        public IList<JSONStopSummary> RoutesServingStop(String code)
        {
            List<JSONStopSummary> results = new List<JSONStopSummary>();
            using (IScheduleInfo db = DB())
            {
                foreach (BusStops stop in CommonQueries.StopByCode(db, code))
                { results.Add(Serializer.Serialize(stop, CommonQueries.RoutesServingStop(db, stop))); }
            }
            return results;
        }

        [RestFunction(Cacheable = true, ExpiryInMinutes = 10)]
        public IEnumerable<JSONStopSummary> NextTrips(IEnumerable<String> codes, [Optional("DEFAULT_TIME_RANGE")] TimeSpan range)
        {
            using (IScheduleInfo db = DB())
            {
                List<JSONStopSummary> result = new List<JSONStopSummary>();
                foreach (String code in codes.Distinct())
                {
                    foreach (BusStops stop in CommonQueries.StopByCode(db, code))
                    {
                        result.Add(Serializer.Serialize(stop, CommonQueries.NextTrips(db, stop, range)));
                    }
                }
                return result;
            }
        }

        [RestFunction(Cacheable = true, ExpiryInMinutes = 10)]
        public IEnumerable<JSONStopSummary> QuickSearch(IEnumerable<String> codes, [Optional("DEFAULT_TIME_RANGE")] TimeSpan range)
        {
            using (IScheduleInfo db = DB())
            {
                List<JSONStopSummary> result = new List<JSONStopSummary>();
                foreach (String code in codes.Distinct())
                {
                    try
                    {
                        foreach (BusStops stop in CommonQueries.StopByCode(db, code))
                        { result.Add(Serializer.Serialize(stop, CommonQueries.NextTrips(db, stop, range), CommonQueries.RoutesServingStop(db, stop))); }
                    }
                    catch (Exception e)
                    { log.Error(e); }
                }
                return result;
            }
        }

        [RestFunction]
        public IEnumerable<JSONStopSummary> QuickSearch(decimal lat, decimal lon, [Optional("DEFAULT_TIME_RANGE")] TimeSpan timerange, double rangeInKm = DEFAULT_RANGE_KM, int maxResults = DEFAULT_MAX_RESULTS)
        {
            using (IScheduleInfo db = DB())
            {
                var stops = CommonQueries.StopsNearPoint(db, lat, lon, rangeInKm, maxResults).Take(5);
                List<JSONStopSummary> result = new List<JSONStopSummary>();
                foreach (BusStops stop in stops)
                { result.Add(Serializer.Serialize(stop, CommonQueries.NextTrips(db, stop, timerange), CommonQueries.RoutesServingStop(db, stop))); }
                return result;
            }
        }
    }
}
